package com.wh.wisdomsite.xbox.server.controller.us;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.wh.wisdomsite.xbox.ba.entity.Menu;
import com.wh.wisdomsite.xbox.ba.entity.Role;
import com.wh.wisdomsite.xbox.ba.entity.SysUserLog;
import com.wh.wisdomsite.xbox.ba.service.IMenuService;
import com.wh.wisdomsite.xbox.ba.service.IRoleCompanyService;
import com.wh.wisdomsite.xbox.ba.service.IRoleService;
import com.wh.wisdomsite.xbox.ba.service.ISysUserLogService;
import com.wh.wisdomsite.xbox.common.Constants;
import com.wh.wisdomsite.xbox.common.reponse.CommonResult;
import com.wh.wisdomsite.xbox.common.util.ResManager;
import com.wh.wisdomsite.xbox.pojo.us.LoginIn;
import com.wh.wisdomsite.xbox.pojo.us.RegisterIn;
import com.wh.wisdomsite.xbox.pojo.us.UserModifyPasswordIn;
import com.wh.wisdomsite.xbox.server.listener.ServerSessionListener;
import com.wh.wisdomsite.xbox.server.manager.UserMapManager;
import com.wh.wisdomsite.xbox.server.session.ServerSessionUser;
import com.wh.wisdomsite.xbox.server.util.UserUtils;
import com.wh.wisdomsite.xbox.us.entity.Company;
import com.wh.wisdomsite.xbox.us.entity.Employee;
import com.wh.wisdomsite.xbox.us.entity.User;
import com.wh.wisdomsite.xbox.us.entity.UserRole;
import com.wh.wisdomsite.xbox.us.service.ICompanyService;
import com.wh.wisdomsite.xbox.us.service.IEmployeeService;
import com.wh.wisdomsite.xbox.us.service.IUserRoleService;
import com.wh.wisdomsite.xbox.us.service.IUserService;
import com.wh.wisdomsite.xbox.utils.Const;
import com.wh.wisdomsite.xbox.utils.SecCode;
import com.wh.wisdomsite.xbox.utils.encrypt.md5.MD5Tool_Two;
import com.wh.wisdomsite.xbox.utils.json.JsonUtil;
import com.wh.wisdomsite.xbox.utils.server.connToserver_HttpClientClose;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.lang.management.ManagementFactory;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 用户登录Controller
 * @Package com.wh.wisdomsite.xbox.server
 * @author 丁奕
 * @date 2018年8月24日 10:17
 * @Copyright 公司版权所有
 * @Company 贵州万华科技有限公司Copyright (c) 2016
 * @version V1.0
 */
@Controller
@RequestMapping("/userLogin")
public class SystemUserController {

    private static final Log logger = LogFactory.getLog(SystemUserController.class);

    @Autowired
    private IUserService iUserService;

    @Autowired
    private ICompanyService iCompanyService;

    @Autowired
    private IRoleCompanyService iRoleCompanyService;

    @Autowired
    private IRoleService iRoleService;

    @Autowired
    private IMenuService iMenuService;

    @Autowired
    private IUserRoleService iUserRoleService;

    @Autowired
    private IEmployeeService iEmployeeService;

    @Autowired
    private ISysUserLogService iSysUserLogService;

    //注册
    private static final String REGIST = "regist";
    //登录
    private static final String LOGIN = "login";
    //改密码
    private static final String UPDATEPWD = "updatePwd";
    //退出系统
    private static final String LOGINOUT = "loginOut";



    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 生成验证码
     * @param response
     */
    @RequestMapping(value = "/generatCode.do", method = RequestMethod.GET)
    public void generatCode(HttpServletResponse response, HttpServletRequest request) {
        try {
            logger.info("用户登录-->>generatCode-->>开始");
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            //生成验证码
            String code = SecCode.drawImg(output);
            logger.info("用户登录-->>generatCode-->> : " + code);
            request.getSession().setAttribute(Constants.SERVER_ADMIN_VALICODE, code);
            //将获取的验证码信息返回到页面
            ServletOutputStream out = response.getOutputStream();
            output.writeTo(out);
            output.flush();
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("用户登录-->>异常 Exception" + e.getMessage());
        }
            logger.info("用户登录-->>generatCode-->>结束");
    }

    @RequestMapping(value = "/register.do", method = RequestMethod.POST)
    public void register(HttpServletResponse response, HttpServletRequest request, RegisterIn registerIn){
        CommonResult commonResult = new CommonResult();
        String userId = "";
        try {
            logger.error("用户登录-->>企业注册-->>开始" );
            //企业名空值判断
            if(StringUtils.isEmpty(registerIn.getCompanyName())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("企业名不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //企业类型空值判断
            if(StringUtils.isEmpty(registerIn.getCompanyType())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("企业类型不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //登录名空值判断
            if(StringUtils.isEmpty(registerIn.getLoginName())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("登录名不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //登录名格式验证
            if(!com.wh.wisdomsite.xbox.utils.StringUtils.isLoginName(registerIn.getLoginName())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("用户名不合法，用户名4到16位（字母，数字，下划线，减号）");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //登录名重复判断
            if(iUserService.loginNameIsExists(registerIn.getLoginName(), null)){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("该用户名已存在!");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }

            //账户密码空值判断
            if(StringUtils.isEmpty(registerIn.getPassword())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("账户密码不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //账户密码格式验证
            if(!com.wh.wisdomsite.xbox.utils.StringUtils.isPassword(registerIn.getPassword())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("账户密码不合法，密码为6-18位的英文或数字组成");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //两次输入密码是否相同判断
            if(!registerIn.getPassword().equals(registerIn.getPasswordEnsure())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("两次密码不一致");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //验证码空判断
            if(StringUtils.isEmpty(registerIn.getValidCode())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("验证码不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            HttpSession session = request.getSession(true);
            String code = session.getAttribute(Constants.SERVER_ADMIN_VALICODE).toString();
            //判断验证码是否正确
            if(!registerIn.getValidCode().equalsIgnoreCase(code)){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("验证码不正确");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //验证都通过，开始取出企业信息，保存企业
            Company company = new Company();
            company.setName(registerIn.getCompanyName());
            company.setCompType(registerIn.getCompanyType());
            iCompanyService.saveCompany(company, null);
            //保存用户信息
            User user = new User();
            user.setLoginName(registerIn.getLoginName());
            user.setUserPhone(registerIn.getPhone());
            user.setCompanyId(company.getCompanyId());
            user.setCreateDate(new Date());
            //给密码加密
            user.setPassword(MD5Tool_Two.MD5(registerIn.getPassword()));
            user.setUsId(UUID.randomUUID().toString().replace("-",""));
            iUserService.insert(user);
            userId = user.getUsId();
            //更新启动时加载的UserMap
            UserMapManager.updateUserToMap(user);
            //给用户绑定默认的运营管理员角色,运营管理员角色为系统数据，固定id为1
            UserRole userRole = new UserRole();
            userRole.setUrId(UUID.randomUUID().toString().replace("-",""));
            userRole.setUsId(user.getUsId());
            userRole.setRoId("1");
            //保存用户角色信息
            iUserRoleService.insert(userRole);
            commonResult.setCode(Constants.CODE_SUCCESS);
            commonResult.setMessage("注册成功");
            getSysUserLog(request,REGIST,null,userId);
            ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
            logger.error("用户登录-->>企业注册-->>结束" );
        }catch (Exception e){
            e.printStackTrace();
            getSysUserLog(request,REGIST,e.getMessage(),userId);
            logger.error("用户登录-->>异常 Exception" + e.getMessage());
            commonResult.setCode(Constants.CODE_FAIL);
            commonResult.setMessage(e.getMessage());
            ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
        }
    }

    /**
     * 登录方法
     * @param response
     * @param in
     */
    @RequestMapping(value = "/login.do", method = RequestMethod.POST)
    public void login(HttpServletResponse response, HttpServletRequest request, LoginIn in){
        CommonResult commonResult = new CommonResult();
        try{
            logger.info("用户登录-->>开始");
            //账户判断
            if(StringUtils.isEmpty(in.getLoginName())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("登录名称不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //账户密码
            if(StringUtils.isEmpty(in.getPassword())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("登录密码不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            //验证码空判断
            if(StringUtils.isEmpty(in.getValidCode())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("登录验证码不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            HttpSession httpSession = request.getSession(true);
            if(httpSession.getAttribute(Constants.SERVER_ADMIN_VALICODE) == null){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("登录验证码已失效");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            String code = httpSession.getAttribute(Constants.SERVER_ADMIN_VALICODE).toString();
            //判断验证码是否正确
            if(!in.getValidCode().equalsIgnoreCase(code)){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("登录验证码不正确");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }

            //用户账号登录
            EntityWrapper<User> ew = new EntityWrapper<User>();
            ew.setEntity(new User());
            ew.eq("loginName", in.getLoginName());
            List<User> userList = iUserService.selectList(ew);

            if(null != userList && userList.size() > 0){
                if(userList.get(0) != null){
                    User user = userList.get(0);
                    in.setPassword(MD5Tool_Two.MD5(in.getPassword()));
                    //判断用户的禁用时间和禁用状态，若被禁用，且当前时间大于禁用时间，要恢复禁用状态
                    if(user.getDisabledTime() != null && user.getDisabledTime().before(new Date()) && user.getLoginStatus().equals("2")){
                        //设置为启用
                        user.setLoginStatus("1");
                        //设置尝试次数为0
                        user.setPwdErrCount(0);
                        //设置禁用时间为null
                        user.setDisabledTime(null);
                    }
                    //状态为禁用用户,且禁用时间大于当前时间,不能登录(登录状态：1：可登录  2：已禁用)
                    if(user.getLoginStatus().equals("2")){
                        commonResult.setCode(Constants.CODE_FAIL);
                        commonResult.setMessage("此用户已被禁用");
                        if(user.getDisabledTime() != null && user.getDisabledTime().after(new Date())){
                            commonResult.setMessage("此用户已被禁用，禁用截止时间为：" + simpleDateFormat.format(user.getDisabledTime()));
                        }
                        ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                        return;
                    }
                    //验证账户密码
                    logger.info("用户账户登录-->>passwordIn: " + in.getPassword());
                    logger.info("用户账户登录-->>passwordUser: " + user.getPassword());
                    logger.info("用户账户登录-->>是否相等: " + user.getPassword().equals(in.getPassword()));
                    if(!in.getPassword().equals(user.getPassword())){
                        Integer pwdErrCount = user.getPwdErrCount();
                        commonResult.setCode(Constants.CODE_FAIL);
                        if(pwdErrCount == null){
                            pwdErrCount = 0;
                        }
                        user.setPwdErrCount(pwdErrCount + 1);
                        //判断是否超过错误次数
                        if(user.getPwdErrCount() < 5){
                            commonResult.setMessage("账号或密码错误,剩余"+(5-user.getPwdErrCount()) +"次尝试机会");
                            ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                        }else{
                            user.setLoginStatus("2");
                            user.setDisabledTime(new Date(new Date().getTime() + 60 * 60 * 24 * 1000));
                            commonResult.setMessage("账号或密码错误,已错误5次，账户被禁用，禁用时间截止至：" + simpleDateFormat.format(user.getDisabledTime()));
                            ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                        }
                        //更新user
                        iUserService.updateById(user);
                        return;
                    }
                    //保存进程名称
                    String processName =  ManagementFactory.getRuntimeMXBean().getName();
                    //存储会话用户
                    String userId = user.getUsId();
                    ServerSessionUser serverSessionUser = getSessionUser(user);
                    serverSessionUser.setSessionId(httpSession.getId());
                    //处理用户登录(保持同一时间同一账号只能在一处登录)使用 同步方法，只允许一个线程进入，才好验证是否重复登录
                    //TODO 正式运行要打开单点登录功能，现在测试环境下先注释掉单点登录的判断
//                    if(ServerSessionListener.checkHasLogin(serverSessionUser)){
//                        ServerSessionListener.removeSessionUser(serverSessionUser.getUser().getUsId(), httpSession.getId());
//                        //Goeasy推送被踢掉线信息
//                        GoEasy goEasy = new GoEasy("BC-f9e55149bfec44d0b672e377bee262e4");
//                        goEasy.publish("userLoginChannel:"+user.getUsId()+ processName, "您的账号已在另一处登陆，您已被迫下线！");
//                        if(null == request.getSession(false)){
//                            logger.info("管理员登录-->>checkHasLogin-->>您的账号已经在另一处登录了,你被迫下线!");
//                        }
//                    }

                    httpSession.setMaxInactiveInterval(30 * 60);
                    //将sessionUser对象放入session
                    httpSession.setAttribute(Constants.SERVER_SESSION_USER, serverSessionUser);
                    httpSession.setAttribute("sysName", "Xbox数据插件系统v2.0版本");
                    httpSession.setAttribute("processName", processName);
                    httpSession.setAttribute("loginStyle", "default");
                    ServerSessionListener.addUserSession(httpSession);

                    //登录成功
                    getSysUserLog(request,LOGIN,null);
                    commonResult.setCode(Constants.CODE_SUCCESS);
                    commonResult.setMessage(Constants.CODE_SUCCESS_MSG);
                    ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                    //更新user
                    user.setLoginDate(new Date());
                    user.setLoginIp(request.getRemoteAddr());
                    user.setPwdErrCount(0);
                    iUserService.updateById(user);
                    return;
                }
            }else{
                //登录失败
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("登陆账号不存在");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            logger.info("用户登录-->>结束");
        }catch(Exception e){
            e.printStackTrace();
            getSysUserLog(request,LOGIN,e.getMessage());
            logger.error("用户登录-->>异常 Exception" + e.getMessage());
            commonResult.setCode(Constants.CODE_FAIL);
            commonResult.setMessage("登录异常，请尝试重新登录");
            ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
            return;
        }
    }

    /**
     * 一体化登录方法
     * @param response
     * @param code
     * @Author 丁奕
     * @Description
     *      在一体化平台触发智慧工地系统登录，传入code，再将code作为参数，
     *      调取一体化平台接口，获取用户信息，完成登录操作。
     */
    @RequestMapping(value = "/ythLogin.do", method = RequestMethod.GET)
    public String ythLogin(HttpServletResponse response, HttpServletRequest request, String code, String redirectUrl){
        try{
            logger.info("一体化用户登录-->>开始");
            HttpSession httpSession = request.getSession(true);

            String url = Const.YTH_LOGIN_URL;
            Map<String, String> map = new HashMap<>();
            map.put("code", code);
//            String userMap = "{\"user\":{\"id\":\"6d93537192a6497f8889c9a409f72c65\",\"isNewRecord\":false,\"remarks\":\"\",\"createDate\":\"2018-09-15 14:48:48\",\"updateDate\":\"2018-09-15 14:48:48\",\"company\":{\"id\":\"ee5c30a6818c469283da253e20468f5c\",\"isNewRecord\":false,\"remarks\":\"\",\"createDate\":\"\",\"updateDate\":\"\",\"parentIds\":\"0,\",\"name\":\"建设单位\",\"sort\":30,\"area\":\"\",\"code\":\"\",\"type\":\"2\",\"grade\":\"\",\"address\":\"\",\"zipCode\":\"\",\"master\":\"\",\"phone\":\"\",\"fax\":\"\",\"email\":\"\",\"useable\":\"\",\"primaryPerson\":\"\",\"deputyPerson\":\"\",\"childDeptList\":\"\",\"corpId\":\"329045077ecd46959da5bfbd8a4b0653\",\"safety\":\"\",\"quality\":\"\",\"parentId\":\"0\"},\"loginName\":\"jsdw\",\"no\":\"\",\"name\":\"建设单位\",\"email\":\"\",\"phone\":\"\",\"mobile\":\"\",\"userType\":\"1\",\"loginIp\":\"未知\",\"loginDate\":\"2019-01-03 11:49:11\",\"loginFlag\":\"1\",\"photo\":\"\",\"companyName\":\"\",\"officeName\":\"\",\"code\":\"\",\"oldLoginName\":\"\",\"newPassword\":\"\",\"oldLoginIp\":\"未知\",\"oldLoginDate\":\"2019-01-03 11:49:11\",\"role\":\"\",\"projectList\":[],\"userCertificateList\":[],\"corpCode\":\"\",\"idNumber\":\"\",\"age\":\"\",\"openId\":\"\",\"job\":\"\",\"certificateType\":\"\",\"certificateNumber\":\"\",\"goodScore\":\"\",\"badScore\":\"\",\"totalScore\":\"\",\"type\":\"\",\"ignoreUserId\":\"\",\"titleAndMajar\":\"\",\"userCertificate\":\"\",\"safeResponbilityPerson\":\"\",\"qualityResponbilityPerson\":\"\",\"corpId\":\"\",\"economicnum\":\"1\",\"isAdmin\":\"\",\"behaviorFlag\":\"\",\"admin\":false,\"roleNames\":\"\"}}";
            String userMap = connToserver_HttpClientClose.sendPostRequest(url, map);
            net.sf.json.JSONObject jsonResult = net.sf.json.JSONObject.fromObject(JSONObject.stringToValue(userMap));
            if(jsonResult.get("user") != null && !jsonResult.get("user").equals("")){
                net.sf.json.JSONObject userJson = net.sf.json.JSONObject.fromObject(jsonResult.get("user"));
                //一体化账户登录
                EntityWrapper<User> ew = new EntityWrapper<User>();
                ew.setEntity(new User());
                ew.eq("openUid", userJson.get("id"));
                User user = iUserService.selectOne(ew);
                //判断本地是否有此条用户数据
                if(user == null){
                    //本地未有此用户信息时,进行注册操作，注册后再进行登陆

                    //验证都通过，开始取出企业信息，根据企业ID查询是否已有此企业，若无则创建，有则返回此企业
                    net.sf.json.JSONObject companyJson = net.sf.json.JSONObject.fromObject(userJson.get("company"));
                    //根据企业ID查询
                    String ythCompanyId = companyJson.get("id").toString();
                    EntityWrapper<Company> ewCompany = new EntityWrapper<>();
                    ewCompany.setEntity(new Company());
                    ewCompany.eq("ythCompanyId", ythCompanyId);
                    Company company = iCompanyService.selectOne(ewCompany);
                    //若查询不到此企业，则创建
                    if(company == null){
                        company = new Company();
                        company.setName(companyJson.get("name").toString());
                        company.setCompType("");
                        company.setYthCompanyId(ythCompanyId);
                        iCompanyService.saveCompany(company, null);
                    }
                    //保存用户信息
                    user = new User();
                    user.setLoginName("yth_" + userJson.get("loginName").toString());
                    user.setUserPhone(null);
                    user.setOpenUid(userJson.get("id").toString());
                    user.setPlatform("yth");
                    user.setCompanyId(company.getCompanyId());
                    user.setCreateDate(new Date());
                    //给密码加密,默认密码123456
                    user.setPassword(MD5Tool_Two.MD5("123456"));
                    user.setUsId(UUID.randomUUID().toString().replace("-",""));
                    iUserService.insert(user);
                    //更新启动时加载的UserMap
                    UserMapManager.updateUserToMap(user);
                    //给用户绑定默认的运营管理员角色,运营管理员角色为系统数据，固定id为1
                    UserRole userRole = new UserRole();
                    userRole.setUrId(UUID.randomUUID().toString().replace("-",""));
                    userRole.setUsId(user.getUsId());
                    userRole.setRoId("1");
                    //若该用户是政府用户或者管理员，再绑定监管部门管理员角色，固定ID为2
                    if(jsonResult.get("type") != null && (jsonResult.get("type").equals("gov") || jsonResult.get("type").equals("manager"))){
                        UserRole userRole2 = new UserRole();
                        userRole2.setUrId(UUID.randomUUID().toString().replace("-",""));
                        userRole2.setUsId(user.getUsId());
                        userRole2.setRoId("2");
                        //保存用户角色信息
                        iUserRoleService.insert(userRole2);
                    }
                    //保存用户角色信息
                    iUserRoleService.insert(userRole);
                }
                //进行登陆操作
                //保存进程名称
                String processName =  ManagementFactory.getRuntimeMXBean().getName();
                //存储会话用户
                ServerSessionUser serverSessionUser = getSessionUser(user);
                serverSessionUser.setSessionId(httpSession.getId());
                //处理用户登录(保持同一时间同一账号只能在一处登录)使用 同步方法，只允许一个线程进入，才好验证是否重复登录
                //TODO 正式运行要打开单点登录功能，现在测试环境下先注释掉单点登录的判断
//                    if(ServerSessionListener.checkHasLogin(serverSessionUser)){
//                        ServerSessionListener.removeSessionUser(serverSessionUser.getUser().getUsId(), httpSession.getId());
//                        //Goeasy推送被踢掉线信息
//                        GoEasy goEasy = new GoEasy("BC-f9e55149bfec44d0b672e377bee262e4");
//                        goEasy.publish("userLoginChannel:"+user.getUsId()+ processName, "您的账号已在另一处登陆，您已被迫下线！");
//                        if(null == request.getSession(false)){
//                            logger.info("管理员登录-->>checkHasLogin-->>您的账号已经在另一处登录了,你被迫下线!");
//                        }
//                    }

                httpSession.setMaxInactiveInterval(60 * 60 * 24 * 7);
                //将sessionUser对象放入session
                httpSession.setAttribute(Constants.SERVER_SESSION_USER, serverSessionUser);
                httpSession.setAttribute("sysName", "Xbox数据插件系统v2.0版本");
                httpSession.setAttribute("processName", processName);
                httpSession.setAttribute("loginStyle", "default");
                ServerSessionListener.addUserSession(httpSession);

                //登录成功
                getSysUserLog(request,LOGIN,null);
                //更新user
                user.setLoginDate(new Date());
                user.setLoginIp(request.getRemoteAddr());
                user.setPwdErrCount(0);
                iUserService.updateById(user);
            }else{
                //未获取到用户信息
            }
            logger.info("一体化用户登录-->>结束");
        }catch(Exception e){
            e.printStackTrace();
            getSysUserLog(request,LOGIN,e.getMessage());
            logger.error("一体化用户登录-->>异常 Exception" + e.getMessage());
        }
        //如果重定向url不为空，则重定向至指定的url
        if(StringUtils.isNotEmpty(redirectUrl)){
            return "redirect:"+redirectUrl;
        }
        return "redirect:main.do";
    }

    /**
     * 根据user获取ServerSessionUser
     * @param user
     * @return
     */
    private ServerSessionUser getSessionUser(User user) {
        ServerSessionUser serverSessionUser = new ServerSessionUser();
        /**
         * 设置用户基本信息
         */
        serverSessionUser.setUser(user);

        /**
         * 设置用户直属公司信息
         */
        Company directCompany = iCompanyService.selectById(user.getCompanyId());
        if(directCompany != null){
            serverSessionUser.setDirectCompany(directCompany);

            /**
             * 设置用户所属总公司信息
             */
            Company headCompany = new Company();
            //直属公司有上级公司去查询总公司
            if(directCompany.getParentId() != 0){
                EntityWrapper<Company> ewCompany = new EntityWrapper<>();
                ewCompany.setEntity(new Company());
                ewCompany.eq("compCode", directCompany.getCompCode().substring(0,3));
                List<Company> companyList = iCompanyService.selectList(ewCompany);
                if(companyList != null && companyList.size() > 0){
                    //获取到所属总公司
                    headCompany = companyList.get(0);
                }
            }else {
                headCompany = directCompany;
            }
            serverSessionUser.setHeadCompany(headCompany);
        }

        /**
         * 设置用户所属员工信息
         */
        if(user.getEmId() != null && !user.getEmId().equals("")){
            Employee employee = iEmployeeService.selectDetailById(user.getEmId());
            if(employee != null){
                serverSessionUser.setEmployee(employee);
            }
        }

        /**
         * 设置员工角色信息
         */
        List<Role> roleList = iRoleService.getRoleListByUserId(user.getUsId());
        //设置用户最终的数据权限
        serverSessionUser.setRoleList(roleList);
        if(roleList != null && roleList.size() > 0){
            serverSessionUser.setDataScope(roleList.get(0).getDataScopeCD().getPropertyCode());
            for(Role role : roleList){
                if(Integer.valueOf(role.getDataScopeCD().getPropertyCode()) < Integer.valueOf(serverSessionUser.getDataScope())){
                    serverSessionUser.setDataScope(role.getDataScopeCD().getPropertyCode());
                }
            }
        }

        /**
         * 设置用户的菜单权限信息
         */
        List<Menu> menuList = iMenuService.getMenuListByUsId(user.getUsId());
        List<Menu> menuTree = iMenuService.toTreeMenuList(menuList);
        serverSessionUser.setMenuList(menuTree);

        JSONArray array = new JSONArray();
        if(menuTree.size() > 0){
            for(Menu menu : menuTree){
                JSONObject object = new JSONObject(menu);
                array.put(object);
            }
        }
        serverSessionUser.setMenuListJson(array.toString());

        Map<String, Menu> permissions = new HashMap<>();
        //遍历所拥有的menuList，将所有权限标识加入permissions
        if(menuList != null && menuList.size() > 0){
            for(Menu menu : menuList){
                if(menu.getPermission() != null && menu.getPermission() != ""){
                    permissions.put(menu.getPermission(), menu);
                }
            }
        }
        serverSessionUser.setPermissions(permissions);
        return serverSessionUser;
    }

    /**
     * 跳转到框架页面
     */
    @RequestMapping(value = "/main.do", method = RequestMethod.GET)
    public String main() {
        return "main/main";
    }

    /**
     * 跳转到首页页面
     * @return
     */
    @RequestMapping(value = "/index.do", method = RequestMethod.GET)
    public String index() {
        return "index";
    }


    /**
     * 修改密码
     * @param response
     * @param request
     * @param userModifyPasswordIn
     */
    @RequestMapping(value = "/modify.do", method = RequestMethod.POST)
    public void modify(HttpServletResponse response, HttpServletRequest request, UserModifyPasswordIn userModifyPasswordIn){
        CommonResult commonResult = new CommonResult();
        try {
            HttpSession session = request.getSession(true);
            String usId = ((ServerSessionUser)session.getAttribute(Constants.SERVER_SESSION_USER)).getUser().getUsId();
            logger.info("修改密码-->>开始");
            //判断密码是否为空
            if(StringUtils.isEmpty(userModifyPasswordIn.getOldPassword()) || StringUtils.isEmpty(userModifyPasswordIn.getNewPassword()) || StringUtils.isEmpty(userModifyPasswordIn.getNewPasswordEnsure())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("新/旧密码不能为空");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            if(!userModifyPasswordIn.getNewPassword().equals(userModifyPasswordIn.getNewPasswordEnsure())){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("两次密码不一致");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }
            EntityWrapper<User> ewUser = new EntityWrapper<>();
            ewUser.setEntity(new User());
            ewUser.eq("usId", usId);

            //获取秘钥
            User user = iUserService.selectOne(ewUser);
            userModifyPasswordIn.setOldPassword(MD5Tool_Two.MD5(userModifyPasswordIn.getOldPassword()));
            //验证旧密码是否正确
            if(user == null || (!user.getPassword().equals(userModifyPasswordIn.getOldPassword()))){
                commonResult.setCode(Constants.CODE_FAIL);
                commonResult.setMessage("旧密码错误");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
                return;
            }else {
                //给新密码加密
                user.setPassword(MD5Tool_Two.MD5(userModifyPasswordIn.getNewPassword()));
                iUserService.updateById(user);
                getSysUserLog(request,UPDATEPWD,null);
                commonResult.setCode(Constants.CODE_SUCCESS);
                commonResult.setMessage("账户密码修改成功");
                ResManager.getJsonOut(response).print(JsonUtil.Json2All(commonResult));
            }
            logger.info("修改密码-->>结束");
        } catch (Exception e){
            e.printStackTrace();
            getSysUserLog(request,UPDATEPWD,e.getMessage());
            logger.error("修改密码-->>异常 Exception" + e.getMessage());
        }
    }


    /**
     * 退出登录
     * @param response
     * @param request
     */
    @RequestMapping("logout")
    public void logout(HttpServletResponse response, HttpServletRequest request) {
        logger.info("退出登录-->>开始");
        Map<String, Object> map = new HashMap<String, Object>();
        try{
            HttpSession session = request.getSession(true);
            Object objSession = session.getAttribute(Constants.SERVER_SESSION_USER);
            if (null != objSession) {
                ServerSessionUser serverSessionUser = (ServerSessionUser) objSession;
                if (null != serverSessionUser && null != serverSessionUser.getSessionId()) {
                    getSysUserLog(request,LOGINOUT,null);
                    ServerSessionListener.removeLoginOutuser(serverSessionUser.getUser().getUsId(), session.getId());
                }
            }
            map.put("code", Constants.CODE_SUCCESS);
            map.put("message", "退出应用系统成功！");
        } catch (Exception e){
            e.printStackTrace();
            getSysUserLog(request,LOGINOUT,e.getMessage());
            map.put("code", Constants.CODE_FAIL);
            map.put("message", "退出应用系统失败！");
            logger.error("退出登录-->>异常 Exception" + e.getMessage());
        }
        ResManager.getJsonOut(response).print(JsonUtil.Json2All(map));
        logger.info("退出登录-->>结束");
    }

    /**
     * 非正常关闭浏览器退出系统
     * @param request
     */
    @RequestMapping("/abnormalLogout.do")
    public void abnormalLogout(HttpServletRequest request) {
        //getSysUserLog(request,LOGINOUT,null);
    }

    /**
     * 用户日志保存
     *
     * @param request
     * @param uslCode
     * @param exception
     * @return
     */
    public void getSysUserLog(HttpServletRequest request, String uslCode, String exception){
        SysUserLog sysUserLog = new SysUserLog();
        String userId = UserUtils.getCurrentUser().getUsId();
        //客户端ip
        String userIp = request.getRemoteAddr();
        //请求路径
        String requestUrl = request.getRequestURI();
        //用户代理
        String userAgent = request.getHeader("user-agent");
        //获取所有的请求参数
        String params = "";
        Enumeration<String> paraNames=request.getParameterNames();
        for(Enumeration<String> e=paraNames;e.hasMoreElements();){
            String thisName=e.nextElement().toString();
            String thisValue=request.getParameter(thisName);
            if(thisName.contains("assword")){
                thisValue = (MD5Tool_Two.MD5(thisValue));
            }
            params = params + thisName + "=" + thisValue + "&";
        }
        String paramsRel = params.length() > 0?params.substring(0,params.length()-1):"";
        sysUserLog.setCreateBy(userId);
        sysUserLog.setCreateDate(new Date());
        sysUserLog.setException(exception);
        sysUserLog.setUslCode(uslCode);
        sysUserLog.setUserIp(userIp);
        sysUserLog.setReqUrl(requestUrl);
        sysUserLog.setUserAgent(userAgent);
        sysUserLog.setParams(paramsRel);
        iSysUserLogService.insert(sysUserLog);
    }

    /**
     * 用户日志保存(供注册方法使用)
     * @param request
     * @param uslCode
     * @param exception
     * @param userId
     */
    public void getSysUserLog(HttpServletRequest request, String uslCode, String exception,String userId){
        SysUserLog sysUserLog = new SysUserLog();
        //客户端ip
        String userIp = request.getRemoteAddr();
        //请求路径
        String requestUrl = request.getRequestURI();
        //用户代理
        String userAgent = request.getHeader("user-agent");
        //获取所有的请求参数
        String params = "";
        Enumeration<String> paraNames=request.getParameterNames();
        for(Enumeration<String> e=paraNames;e.hasMoreElements();){
            String thisName=e.nextElement().toString();
            String thisValue=request.getParameter(thisName);
            if(thisName.contains("assword")){
                thisValue = (MD5Tool_Two.MD5(thisValue));
            }
            params = params + thisName + "=" + thisValue + "&";
        }
        String paramsRel = params.length() > 0?params.substring(0,params.length()-1):"";
        sysUserLog.setCreateBy(userId);
        sysUserLog.setCreateDate(new Date());
        sysUserLog.setException(exception);
        sysUserLog.setUslCode(uslCode);
        sysUserLog.setUserIp(userIp);
        sysUserLog.setReqUrl(requestUrl);
        sysUserLog.setUserAgent(userAgent);
        sysUserLog.setParams(paramsRel);
        iSysUserLogService.insert(sysUserLog);
    }

}
